/*
 * @Description: 
 * @Author: rendc
 * @Date: 2024-10-12 16:20:30
 * @LastEditors: rendc
 * @LastEditTime: 2024-10-12 17:00:46
 */
/**
 * Account
 */
public class Account {
  private String name; // 账户名称
  private double balance; // 账户余额
  // 全参构造器

  public Account(String name, double balance) {
    this.name = name;
    this.balance = balance;
  }

  // 存款
  public void addMoney(double money) {
    balance += money;
  }

  // 取款
  public void subMoney(double money) {
    balance -= money;
  }

  // 查询余额
  public double getBalance() {
    return balance;
  }

  // 查询账户名
  public String getName() {
    return name;
  }

  // 转账
  public void transfer(Account to, double amount) {
    // 3. 在进行转账操作时，需要按照账户名称的字典序进行排序，保证转账过程中的资源占用顺序一致，避免死锁的出现。
    Account firstAccount = (name.compareTo(to.getName()) < 0) ? this : to;
    Account secondAccount = (name.compareTo(to.getName()) < 0) ? to : this;
    synchronized (firstAccount) {
      synchronized (secondAccount) {
        // 需要同步的代码 - 开始
        // 1. 用户可以同时进行多次转账操作，
        // 每次转账的金额必须大于0，同时转出账户余额必须大于等于转账金额。
        if (balance >= amount) {
          subMoney(amount);// 自己的余额要减小
          to.addMoney(amount); // 对方账户的余额要增加
          // 并输出转账的金额和最新的账户余额。
          System.out.println("转账成功," + to.getName() + "到账" + amount + "元");
          System.out.println(this.getName() + "账户余额：" + balance + "元");
        } else {
          System.out.println(this.getName() + "余额不足，账户余额：" + balance + "元");
        }
        // 2. 转账过程中，需要对转出账户和转入账户加锁，保证同时只能有一个线程对某个账户进行转账操作。
        // 4. 转账操作完成后，需要释放相应的锁，
        // 需要同步的代码 - 结束
      }
    }
  }
}